﻿using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;

namespace Infrastructure.Utils.Tool
{
    public class XmlHelper
    {
        #region 实体对象序列化成xml字符串
        /// <summary>
        /// T > xml [实体对象序列化成xml字符串 ] 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">T</param>
        /// <param name="encoding">encoding</param>
        /// <param name="rootName">跟节点名称：默认对象名</param>
        /// <param name="isNeednamespaces">是否需要命名空间</param>
        /// <param name="isNeedStatement">是否需要声明</param>
        /// <returns></returns>
        public static string ToXml<T>(T obj, Encoding encoding = default, string rootName = null, bool isNeednamespaces = true, bool isNeedStatement = true)
        {
            if (obj == null) throw new ArgumentNullException("object");
            var xmlSerializer = rootName == null ? new XmlSerializer(obj.GetType()) : new XmlSerializer(obj.GetType(), new XmlRootAttribute(rootName));

            using (var ms = new MemoryStream())
            {
                using (var writer = new XmlTextWriter(ms, encoding))
                {
                    writer.Formatting = Formatting.Indented;//美化
                    if (isNeednamespaces)
                    {
                        xmlSerializer.Serialize(writer, obj);
                    }
                    else
                    {
                        var _namespaces = new XmlSerializerNamespaces();
                        _namespaces.Add("", "");
                        xmlSerializer.Serialize(writer, obj, _namespaces);
                    }
                }
                var xml = encoding.GetString(ms.ToArray());
                if (!isNeedStatement) xml = Regex.Replace(xml, @"^[﻿]?<\?.*\?>", "").Trim();
                return xml;
            }
        }
        #endregion

        #region xml字符转对象
        /// xml字符转对象 
        /// </summary>  
        /// <typeparam name="T"></typeparam>  
        /// <param name="xml"></param>  
        /// <param name="encoding"></param>  
        /// <returns></returns>  
        public static T ToObject<T>(string xml, Encoding encoding) where T : new()
        {
            var mySerializer = new XmlSerializer(typeof(T));
            using (var ms = new MemoryStream(encoding.GetBytes(xml)))
            {
                using (var sr = new StreamReader(ms, encoding))
                {
                    return (T)mySerializer.Deserialize(sr);
                }
            }
        }
        #endregion
    }
}
